package com.shiro.config;

import java.util.concurrent.atomic.AtomicInteger;
import com.shiro.pojo.User;
import com.shiro.service.UserService;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.Configuration;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * @author ZhangJunqi
 * @Date 2022/3/10 -20:57
 */
public class RetryLimitHashedCredentialsMatcher extends SimpleCredentialsMatcher {
    @Autowired
    private UserService userService;
    private Cache<String, AtomicInteger> passwordRetryCache;
    //net.sf.ehcache.config.CacheConfiguration
    private  CacheConfiguration ehcache_config_cacheConfiguration;
    //最大密码错误次数
    private int retryLimitNum;
    public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {
        //org.apache.shiro.cache.CacheManager 是缓存cache最大的父类接口
        //EhCacheManager implements CacheManager
        EhCacheManager ehCacheManager= (EhCacheManager) cacheManager;
        //net.sf.ehcache.CacheManager
        net.sf.ehcache.CacheManager cacheManager1=ehCacheManager.getCacheManager ();
        //net.sf.ehcache.config.Configuration
        Configuration cacheConfiguration= cacheManager1.getConfiguration ();
        //该Configuration声明了private CacheConfiguration defaultCacheConfiguration;
        //net.sf.ehcache.config.CacheConfiguration
        ehcache_config_cacheConfiguration= cacheConfiguration.getDefaultCacheConfiguration ();
        System.out.println ("ehcache_config_cacheConfiguration.getTimeToIdleSeconds () = " + ehcache_config_cacheConfiguration. getTimeToIdleSeconds ());
        //setTimeToIdleSeconds(long timeToIdleSeconds)
        passwordRetryCache = cacheManager.getCache("passwordRetryCache");
    }

    public RetryLimitHashedCredentialsMatcher() {

    }
    public int getRetryLimitNum() {
        return retryLimitNum;
    }

    public RetryLimitHashedCredentialsMatcher setRetryLimitNum(int retryLimitNum) {
        this.retryLimitNum = retryLimitNum;
        return this;
    }

    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {

        //获取用户名
        String username = (String)token.getPrincipal();
        //获取用户登录次数
        AtomicInteger retryCount = passwordRetryCache.get(username);
        System.out.println("登录次数："+retryCount);
        if (retryCount == null) {
            //如果用户没有登陆过,登陆次数加1 并放入缓存
            retryCount = new AtomicInteger(0);
            passwordRetryCache.put(username, retryCount);
        }
        if (retryCount.incrementAndGet() > getRetryLimitNum()) {
            //如果用户登陆失败次数大于设置次数 抛出锁定用户异常，时间为缓存配置时间
            User user = userService.getUserByName (username);
            if (user != null && user.getUserStatus ()==0){
                //数据库字段 默认为 0  就是正常状态 所以 要改为1
                //修改数据库的状态字段为锁定
               /* user.setUserStatus (1);
                int res=userService.updateUser(user);*/
            }
            System.out.println("锁定用户:" + user.getUserName ());
            //抛出用户锁定异常
            throw new LockedAccountException ();
        }
        //判断用户账号和密码是否正确
        boolean matches = super.doCredentialsMatch(token, info);
        if (matches) {
            //如果正确,从缓存中将用户登录计数 清除
            passwordRetryCache.remove(username);
        }
        return matches;
    }
    /**
     * 根据用户名 解锁用户
     * @param username
     * @return
     */
    public void unlockAccount(String username){
//        User user = userMapper.findByUserName(username);
//        if (user != null){
//            //修改数据库的状态字段为锁定
//            user.setState("0");
//            userMapper.update(user);
//            passwordRetryCache.remove(username);
//        }
    }


}